/*
 * @(#)ListDmsEmailArchiveAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */

package com.dcivision.dms.web;

import java.util.ArrayList;
import java.util.List;

import javax.mail.AuthenticationFailedException;
import javax.mail.MessagingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.dms.DmsErrorConstant;
import com.dcivision.dms.core.DocumentEmailArchiveManager;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.Crypt;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.web.AbstractListAction;
import com.dcivision.framework.web.AbstractSearchForm;
import com.dcivision.mail.bean.EmailMessage;
import com.dcivision.mail.bean.EmailMessageImpl;
import com.dcivision.mail.bean.MailSetting;
import com.dcivision.mail.core.EmailMessageSorter;
import com.dcivision.mail.core.EmailReceiver;
import com.dcivision.mail.core.EmailReceiverFactory;
import com.dcivision.mail.dao.MailSettingDAObject;

/**
 ListDmsEmailArchiveAction.java

 This class about list email messages list.

 @author      Beyond Qu
 @company     DCIVision Limited
 @creation date   10/06/2005
 @version     $Revision: 1.26.2.2 $
 */

public class ListDmsEmailArchiveAction extends AbstractListAction {

  public static final String REVISION = "$Revision: 1.26.2.2 $";

  protected final static String MESSAGE_RECORD_INSERT = "common.message.record_inserted";


  
  public ListDmsEmailArchiveAction() {
    super();
    this.setListName("dmsEmailList");
  }

  /**
   * getMajorDAOClassName
   * 
   * @return The class name of the major DAObject will be used in this action.
   */
  public String getMajorDAOClassName() {
    return ("com.dcivision.dms.dao.DmsEmailMessageDAObject");
  }

  /**
   * getFunctionCode
   * 
   * @return The corresponding system function code of action.
   */
  public String getFunctionCode() {
    return (SystemFunctionConstant.DMS_EMAIL_ARCHIVE);
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws ServletException {
    
    AbstractSearchForm searchForm = (AbstractSearchForm)form;
    String opMode = searchForm.getOpMode();
    if (GlobalConstant.NAV_MODE_LIST.equals(opMode)
        || GlobalConstant.OP_MODE_LIST_RETAIN.equals(opMode)) {
      opMode = "";
    }

    // Set the function code for current action.
    ActionForward forward = this.retrieveFunctionCode(request, response,
        mapping);
    if (forward != null) {
      return forward;
    }   
    if (!Utility.isEmpty(opMode)) {
      if (GlobalConstant.OP_MODE_DELETE.equals(searchForm.getOpMode())) {
        try{  
          this.deleteListData(mapping, searchForm, request, response);        
          addMessage(request, MESSAGE_RECORDS_DELETED, ""+searchForm.getBasicSelectedID().length);
          searchForm.setBasicSelectedID(null);
          searchForm.setOpMode(null);
        } catch (ApplicationException e) {
          this.rollback(request);
          this.handleApplicationException(request, e);
        } catch (Exception e){
          this.rollback(request);
          log.debug(e.toString());
        }
      }else if ("Save_EMAIL".equals(opMode)) { //opMode
        try {
          saveEmailList(mapping, searchForm,request, response);
          this.commit(request);
          addMessage(request, MESSAGE_RECORD_INSERT);
        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        } catch (Exception e){
          this.rollback(request);
          log.debug(e.toString());
        }
      } else if ("RECEIVE_EMAIL".equals(opMode)) {//opMode
        try {
          receiveEmail(mapping, searchForm, request, response);
          this.commit(request);
        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        }catch (Exception e){
          this.rollback(request);
          log.debug(e.toString());
        }        
      }else if ("To_Rule".equals(opMode)) {//opMode
        try {          
          this.emailToRule(mapping, searchForm, request, response);
          this.commit(request);
        } catch (ApplicationException appEx) {
          this.rollback(request);
          handleApplicationException(request, appEx);
        }catch (Exception e){
          this.rollback(request);
          log.debug(e.toString());
        }        
      }
    }
    
    try {
      this.getListData(mapping, searchForm, request, response);
      List resultList = (List)request.getAttribute(this.m_sListName);
      while ( (resultList.size()==0) && (TextUtility.parseInteger(searchForm.getCurStartRowNo())>TextUtility.parseInteger(searchForm.getPageOffset())) ) {
        int prvRowNo = TextUtility.parseInteger(searchForm.getCurStartRowNo())-TextUtility.parseInteger(searchForm.getPageOffset());
        searchForm.setCurStartRowNo(TextUtility.formatInteger(prvRowNo));
        this.getListData(mapping, searchForm, request, response);
      }
        
    } catch (ApplicationException appEx) {
      this.rollback(request);
      handleApplicationException(request, appEx);
    } catch (Exception e){
      this.rollback(request);
      log.debug(e.toString());
    }    
    
    searchForm.setNavMode(GlobalConstant.NAV_MODE_LIST);    
    searchForm.setOpMode("");    
    return mapping.findForward(GlobalConstant.NAV_MODE_LIST);

  }

  /**
   *  Method getListData() - retrieve the appropriate item list for current page
   *
   *  @param      mapping               ActionMapping from struts
   *  @param      form                  ActionForm from struts
   *  @param      request               HttpServletReuqest
   *  @param      respond               HttpServletRespond
   *  @return     void
   *  @throws     ApplicationException  Throws Exception if cannot get the list data from DAO object
   */
  public void getListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {    
    ListDmsEmailArchiveForm searchForm = (ListDmsEmailArchiveForm)form;
    String opMode = searchForm.getOpMode();
    //get mail sestting information
    MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
    Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
    MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);
    if (mailSetting == null){
        this.addMessage(request,"dms.emailarchive.notSetEmailAccount");
    }else{
      searchForm.setMailSetting(mailSetting);
    }    
    
    // if the folder is null ,then clear the mail list
    List emailList = (List)request.getSession().getAttribute("sessEmailList");
    if(!"RECEIVE_EMAIL".equals(opMode)){
      // auto receiveEmail
      if (Utility.isEmpty(emailList)) {      
        if (mailSetting != null){
          receiveEmail(mapping, form, request, response);
          emailList = (List)request.getSession().getAttribute("sessEmailList");
        }
      }
    }
    
    List resultList = new ArrayList();
    
    String keyword = searchForm.getBasicSearchKeyword();
    String searchType = searchForm.getBasicSearchType();
    List mailList = new ArrayList();
    if (!Utility.isEmpty(searchType) && !Utility.isEmpty(keyword) && !Utility.isEmpty(emailList)){
      for(int i = 0;i<emailList.size() ;i++){
        EmailMessage emailMessage = (EmailMessage)emailList.get(i);
        if(Utility.isEmpty(emailMessage) || Utility.isEmpty(emailMessage.getSubject())){
          continue;    
        }                
        if("=".equals(searchType) && emailMessage.getSubject().toUpperCase().equals(keyword.toUpperCase())){
          mailList.add(emailMessage);    
        }else if("LIKE".equals(searchType) && emailMessage.getSubject().toUpperCase().indexOf(keyword.toUpperCase()) != -1){
          mailList.add(emailMessage);
        }
     }
    }else{
     mailList = emailList;
    }    
    
    //sort list
    String sortAttribute=searchForm.getSortAttribute();
    String sortOrder=searchForm.getSortOrder();
    //reset rowNum
    List sortedResultList = new ArrayList();
    if(!Utility.isEmpty(mailList)){
      List tempList = EmailMessageSorter.sortEmailMessageList(mailList,sortAttribute,sortOrder);
      for(int i = 0;i< tempList.size() ;i++){
        EmailMessage emailMessageImpl = (EmailMessage)tempList.get(i);
        sortedResultList.add(emailMessageImpl);    
      }
    }    
    
    // page split
    int startOffset = TextUtility.parseInteger(searchForm.getCurStartRowNo());
    int pageSize = TextUtility.parseInteger(searchForm.getPageOffset());    
    int rowNum = startOffset;
    if(sortedResultList !=null ){
      for(int i = 0 ;i < sortedResultList.size();i++){
        com.dcivision.framework.bean.AbstractBaseObject emailMessageImpl = (com.dcivision.framework.bean.AbstractBaseObject)sortedResultList.get(i);
        if(startOffset <= (i+1) && (i+1) < startOffset + pageSize) {
          emailMessageImpl.setRecordCount(mailList.size());
          emailMessageImpl.setRowNum(rowNum++);
          resultList.add(emailMessageImpl);                
        }
      }
    }

    
    request.setAttribute(this.m_sListName, resultList);    
  }    
    
  /**
   *  Method saveEmailList()
   *
   *  @param      mapping               ActionMapping from struts
   *  @param      form                  ActionForm from struts
   *  @param      request               HttpServletReuqest
   *  @param      respond               HttpServletRespond
   *  @return     void
   *  @throws     ApplicationException  Throws Exception if cannot get the list data from DAO object
   */
  public void saveEmailList(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {  
    //get mail account information
    MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
    Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
    MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);  
    DocumentEmailArchiveManager manager = new DocumentEmailArchiveManager(this.getSessionContainer(request), this.getConnection(request),mailSetting.getMailServerType());    
    manager.saveEmailListAsCompundDocuments(request);
  }   
  


  public void deleteListData(ActionMapping mapping, AbstractSearchForm form,HttpServletRequest request, HttpServletResponse response)throws ApplicationException {      
      String[] messageIDs = form.getBasicSelectedID();      
      List emailList = (List) request.getSession().getAttribute("sessEmailList");  
      List resultList = new ArrayList();
      // here is replace the sessEmailList, if saved email will be marked
      if(Utility.isEmpty(emailList )){
        return;
      }
      for (int i = 0; i < emailList.size(); i++) {
        boolean isDeletedID = false;
        EmailMessageImpl email = (EmailMessageImpl) emailList.get(i);        
        for (int j = 0; j < messageIDs.length; j++) {
          // if messageIDs conent  email's id ,then delete this email  
          if (messageIDs[j].equals(email.getID().toString())) {
            isDeletedID = true;
            break;
          }
        }
        if(!isDeletedID){
          resultList.add(email);
        }
      }
      
      request.getSession(true).setAttribute("sessEmailList", resultList);
  }    
  
  /** Method receiveEmail()
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
  */
  private void receiveEmail(ActionMapping mapping,AbstractSearchForm form, HttpServletRequest request,HttpServletResponse response) throws ApplicationException {
    try {
      request.getSession().setAttribute("sessEmailList", null);
            
      //Get email account      
      MailSettingDAObject msDAO = new MailSettingDAObject(this.getSessionContainer(request),
                    this.getConnection(request));
            
      MailSetting ms = (MailSetting) msDAO.getObjectByUserRecordID(this.getSessionContainer(request).getUserRecordID());
      String password = Crypt.decrypt(ms.getIncomingServerLoginPwd(),SystemParameterFactory.getSystemParameter(SystemParameterConstant.CRYPTO_SALT));
            
      //get mail 
      EmailReceiver mailReceiver = EmailReceiverFactory.getEmailReceiverInstanceByServerType(this.getSessionContainer(request),ms.getMailServerType());
      //long startTime = 0;
      List list = mailReceiver.loadMailList(ms.getIncomingServerHost(),ms.getIncomingServerLoginName(), password, ms.getMailServerType());
            
      if (Utility.isEmpty(list)) {
        this.addMessage(request, "dms.emailarchive.no_email_receive");
      }
      request.getSession(true).setAttribute("sessEmailList", list);
      request.getSession(true).setAttribute("folder",mailReceiver.getFolder());
    } catch (AuthenticationFailedException afe) {
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_LOGINFAIL, afe);
    } catch (MessagingException e) {
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_CONNECT_ERROR, e);
    } catch (ApplicationException e) {
      throw e;      
    } catch (Exception e) {
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_TO_DOWNLOAD_EMAIL , e);           
    }
  }
  
  /**
   *  Method emailToRule()
   *
   *  @param      mapping               ActionMapping from struts
   *  @param      form                  ActionForm from struts
   *  @param      request               HttpServletReuqest
   *  @param      respond               HttpServletRespond
   *  @return     void
   *  @throws     ApplicationException  Throws Exception if cannot get the list data from DAO object
   */
  public void emailToRule(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {  
    //get mail account information
    MailSettingDAObject msd = new MailSettingDAObject(this.getSessionContainer(request), this.getConnection(request));
    Integer userRecordID = this.getSessionContainer(request).getUserRecordID();
    MailSetting mailSetting = (MailSetting) msd.getObjectByUserRecordID(userRecordID);  
    DocumentEmailArchiveManager manager = new DocumentEmailArchiveManager(this.getSessionContainer(request), this.getConnection(request),mailSetting.getMailServerType());    
    manager.setEmailListToRule(request);
  }   
  
  
}